package com.adcc.loadsheet.monitor.util;

import com.adcc.aoc.devLib.common.log.Log;
import com.adcc.aoc.devLib.common.xml.*;
import com.adcc.loadsheet.monitor.entity.MsgAlarmConfig;;
import com.adcc.loadsheet.monitor.entity.UDPConfig;
import com.adcc.loadsheet.monitor.vo.IgnoreAlarmVO;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.annotation.PostConstruct;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 系统配置工厂
 */
@Component
public class SystemConfigFactory {

    // 配置文件
    private static final String CONFIG_FILE_NAME = "systemConfig.xml";

    // bgs配置Map
    private Map<String, Object> bgsConfigMap = Maps.newHashMap();

    // database配置Map
    private Map<String, Object> databaseConfigMap = Maps.newHashMap();

    // mq系统配置
    private Map<String, Object> mqConfigMap = Maps.newHashMap();

    // appupload配置Map
    private Map<String, Object> appUploadConfigMap = Maps.newHashMap();

    // airInfo配置Map
    private Map<String, Object> airInfoConfigMap = Maps.newHashMap();

    // msgupcenter配置Map
    private Map<String, Object> msgUpCenterConfigMap = Maps.newHashMap();

    // website配置Map
    private Map<String, Object> websiteConfigMap = Maps.newHashMap();

    // 舱单抓取程序配置Map
    private Map<String, Object> forwarderConfigMap = Maps.newHashMap();

    //忽略告警项
    private Map<String, Object> ignoreAlarmMap = Maps.newHashMap();

    //禁止非admin用户操作重启
    private Map<String, Object> roleDisableMap = Maps.newHashMap();

    // 忽略项集合
    private Set<String> alarmIgnoreSet = new HashSet<>();

    public Map<String, Object> getBgsConfigMap() {
        return bgsConfigMap;
    }

    public Map<String, Object> getDatabaseConfigMap() {
        return databaseConfigMap;
    }

    public Map<String, Object> getMqConfigMap() {
        return mqConfigMap;
    }

    public Map<String, Object> getAppUploadConfigMap() {
        return appUploadConfigMap;
    }

    public Map<String, Object> getAirInfoConfigMap() {
        return airInfoConfigMap;
    }

    public Map<String, Object> getMsgUpCenterConfigMap() {
        return msgUpCenterConfigMap;
    }

    public Map<String, Object> getWebsiteConfigMap() {
        return websiteConfigMap;
    }

    public Map<String, Object> getForwarderConfigMap() {
        return forwarderConfigMap;
    }

    public Map<String, Object> getIgnoreAlarmConfigMap() {
        return ignoreAlarmMap;
    }

    public Map<String, Object> getRoleDisable() {
        return roleDisableMap;
    }

    public Set<String> getAlarmIgnoreSet() {
        return alarmIgnoreSet;
    }

    /**
     * 初始化方法
     */
    @PostConstruct
    private void initialize() {
        FileInputStream fis = null;
        try {
            File file = FileUtil.readFile(CONFIG_FILE_NAME);
            if (file != null) {
                fis = new FileInputStream(file);
                load(fis);
            } else {
                Log.error(SystemConfigFactory.class, "load system config file failed " + CONFIG_FILE_NAME + " is not exists");
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "initialize() error", ex);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException ex) {
                    Log.error(SystemConfigFactory.class, "close io error", ex);
                }
            }
        }
    }

    /**
     * 清理系统配置内存
     */
    private void clear() {

        if (bgsConfigMap.size() > 0) {
            bgsConfigMap.clear();
        }

        if (databaseConfigMap.size() > 0) {
            databaseConfigMap.clear();
        }

        if (mqConfigMap.size() > 0) {
            mqConfigMap.clear();
        }

        if (appUploadConfigMap.size() > 0) {
            appUploadConfigMap.clear();
        }

        if (airInfoConfigMap.size() > 0) {
            airInfoConfigMap.clear();
        }

        if (msgUpCenterConfigMap.size() > 0) {
            msgUpCenterConfigMap.clear();
        }

        if (websiteConfigMap.size() > 0) {
            websiteConfigMap.clear();
        }

        if (forwarderConfigMap.size() > 0) {
            forwarderConfigMap.clear();
        }
        if (ignoreAlarmMap.size() > 0) {
            ignoreAlarmMap.clear();
        }
    }

    /**
     * 加载配置
     *
     * @param is
     * @throws Exception
     */
    private void load(InputStream is) {
        try {
            // 清理系统配置内容
            clear();

            ADCCXML adccxml = ADCCXMLFactory.getInstance().createADCCXML();
            adccxml.parse(is);
            Map<String, String> root = adccxml.getRoot();
            if (root.containsKey("type") && "systemConfig".equals(root.get("type"))) {

                // 读取bgs节点
                SuperNode bgsNode = adccxml.getSuperNode("bgs");
                if (bgsNode == null) {
                    Log.error(SystemConfigFactory.class, "missing <bgs></bgs>");
                    throw new Exception("missing <bgs></bgs>");
                }
                bgsConfigMap = parseBgsConfig(bgsNode);

                // 读取database节点
                SuperNode databaseNode = adccxml.getSuperNode("database");
                if (databaseNode == null) {
                    Log.error(SystemConfigFactory.class, "missing <database></database>");
                    throw new Exception("missing <database></database>");
                }
                databaseConfigMap = parseDatabaseConfig(databaseNode);


                // 读取mq节点
                SuperNode mqNode = adccxml.getSuperNode("mq");
                if (mqNode == null) {
                    Log.error(SystemConfigFactory.class, "missing <mq></mq>");
                    throw new Exception("missing <mq></mq>");
                }
                mqConfigMap = parseMqConfig(mqNode);

                // 读取appupload节点
                SuperNode appUploadNode = adccxml.getSuperNode("appupload");
                if (appUploadNode == null) {
                    Log.error(SystemConfigFactory.class, "missing <appupload></appupload>");
                    throw new Exception("missing <appupload></appupload>");
                }
                appUploadConfigMap = parseAppUploadConfig(appUploadNode);

                // 读取airInfo节点
                SuperNode airInfoNode = adccxml.getSuperNode("airInfo");
                if (airInfoNode == null) {
                    Log.error(SystemConfigFactory.class, "missing <airInfo></airInfo>");
                    throw new Exception("missing <airInfo></airInfo>");
                }
                airInfoConfigMap = parseAirInfoConfig(airInfoNode);

                // 读取appupload节点
                SuperNode msgUpCenterNode = adccxml.getSuperNode("msgupcenter");
                if (msgUpCenterNode == null) {
                    Log.error(SystemConfigFactory.class, "missing <msgupcenter></msgupcenter>");
                    throw new Exception("missing <msgupcenter></msgupcenter>");
                }
                msgUpCenterConfigMap = parseMsgUpCenterConfig(msgUpCenterNode);

                // 读取website节点
                SuperNode websiteNode = adccxml.getSuperNode("website");
                if (websiteNode == null) {
                    Log.error(SystemConfigFactory.class, "missing <website></website>");
                    throw new Exception("missing <website></website>");
                }
                websiteConfigMap = parseWebsiteConfig(websiteNode);

                // 读取舱单抓取节点
                SuperNode forwarderNode = adccxml.getSuperNode("forwarder");
                if (forwarderNode == null) {
                    Log.error(SystemConfigFactory.class, "missing <forwarder></forwarder>");
                    throw new Exception("missing <forwarder></forwarder>");
                }
                forwarderConfigMap = parseForwarderConfig(forwarderNode);

                // 读取忽略配置项
                SuperNode alarm = adccxml.getSuperNode("alarm");
                if (alarm == null) {
                    Log.error(SystemConfigFactory.class, "missing <alarm></alarm>");
                    throw new Exception("missing <alarm></alarm>");
                }
                try {
                    ignoreAlarmMap = parseALarmIgnore();
                    // 告警时用
                    alarmIgnoreSet = getIgnoreAlarmSet();
                } catch (Exception e) {
                    Log.error(SystemConfigFactory.class, "missing <alarm></alarm>");
                    throw new Exception("missing <alarm></alarm>");
                }
                //读取禁止非admin用户重启
                SuperNode roleDisable = adccxml.getSuperNode("permissions");
                if (roleDisable == null) {
                    Log.error(SystemConfigFactory.class, "missing <permissions></permissions>");
                    throw new Exception("missing <permissions></permissions>");
                }
                try {
                    roleDisableMap = parseRoleDisable(roleDisable);
                } catch (Exception e) {
                    Log.error(SystemConfigFactory.class, "missing <permissions></permissions>");
                    throw new Exception("missing <permissions></permissions>");
                }
                Log.info("parse xml success");
            } else {
                throw new Exception("<adcc></adcc> missing type or type is not systemConfig");
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "load() error", ex);
        }
    }

    /**
     * 解析bgs配置
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseBgsConfig(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("healthCheck".equals(n.getName())) {
                    resultMap.put("healthCheck", Strings.nullToEmpty(n.getText()));
                }
                if ("remark".equals(n.getName())) {
                    resultMap.put("remark", parseRemarkNode(n));
                }
            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseBgsConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 解析database配置
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseDatabaseConfig(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("warn".equals(n.getName())) {
                    resultMap.put("warn", Strings.nullToEmpty(n.getText()));
                }

                if ("error".equals(n.getName())) {
                    resultMap.put("error", Strings.nullToEmpty(n.getText()));
                }

                if ("diskUsage".equals(n.getName())) {
                    resultMap.put("diskUsage", Strings.nullToEmpty(n.getText()));
                }

                if ("tablespaceUsage".equals(n.getName())) {
                    resultMap.put("tablespaceUsage", Strings.nullToEmpty(n.getText()));
                }
                if ("remark".equals(n.getName())) {
                    resultMap.put("remark", parseRemarkNode(n));
                }
            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseDatabaseConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 解析mq配置
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseMqConfig(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("url".equals(n.getName())) {
                    resultMap.put("url", Strings.nullToEmpty(n.getText()));
                }

                if ("uplinkTopic".equals(n.getName())) {
                    resultMap.put("uplinkTopic", Strings.nullToEmpty(n.getText()));
                }

                if ("downlinkTopic".equals(n.getName())) {
                    resultMap.put("downlinkTopic", Strings.nullToEmpty(n.getText()));
                }
                if ("remark".equals(n.getName())) {
                    resultMap.put("remark", parseRemarkNode(n));
                }

            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseMqConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 解析appUpload配置
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseAppUploadConfig(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("udp".equals(n.getName())) {
                    resultMap.put("udp", parseUDPNode(n));
                }

                if ("msgSplit".equals(n.getName())) {
                    Map<String, String> map = Maps.newHashMap();
                    n.getSubNodeList().forEach(s -> {
                        if ("failureAlarm".equals(s.getName())) {
                            map.put("failureAlarm", Strings.nullToEmpty(s.getText()));
                        }
                    });
                    resultMap.put("msgSplit", map);
                }

                if ("ntp".equals(n.getName())) {
                    resultMap.put("ntp", parseNTPNode(n));
                }

                if ("remark".equals(n.getName())) {
                    resultMap.put("remark", parseRemarkNode(n));
                }

            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseAppUploadConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 解析航信配置
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseAirInfoConfig(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("url".equals(n.getName())) {
                    resultMap.put("url", Strings.nullToEmpty(n.getText()));
                }

                if ("topic".equals(n.getName())) {
                    resultMap.put("topic", Strings.nullToEmpty(n.getText()));
                }

                if ("msgAlarm".equals(n.getName())) {
                    List<MsgAlarmConfig> list = Lists.newArrayList();
                    n.getSubNodeList().forEach(s -> {
                        list.add(parseMsgAlarmNode(s));
                    });
                    resultMap.put("msgAlarm", list);
                }
                if ("remark".equals(n.getName())) {
                    resultMap.put("remark", parseRemarkNode(n));
                }
            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseAirInfoConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 解析msgUpCenter配置
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseMsgUpCenterConfig(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("udp".equals(n.getName())) {
                    resultMap.put("udp", parseUDPNode(n));
                }

                if ("ntp".equals(n.getName())) {
                    resultMap.put("ntp", parseNTPNode(n));
                }

                if ("lineChart".equals(n.getName())) {
                    Map<String, String> map = Maps.newHashMap();
                    n.getSubNodeList().forEach(s -> {
                        if ("timespan".equals(s.getName())) {
                            map.put("timespan", Strings.nullToEmpty(s.getText()));
                        }
                        if ("points".equals(s.getName())) {
                            map.put("points", Strings.nullToEmpty(s.getText()));
                        }
                    });
                    resultMap.put("lineChart", map);
                }
                if ("remark".equals(n.getName())) {
                    resultMap.put("remark", parseRemarkNode(n));
                }
            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseMsgUpCenterConfig() error", ex);
            throw ex;
        }
    }


    /**
     * 解析网站配置
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseWebsiteConfig(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("url1".equals(n.getName())) {
                    resultMap.put("url1", Strings.nullToEmpty(n.getText()));
                }

                if ("url2".equals(n.getName())) {
                    resultMap.put("url2", Strings.nullToEmpty(n.getText()));
                }

                if ("remark".equals(n.getName())) {
                    resultMap.put("remark", parseRemarkNode(n));
                }
            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseWebsiteConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 解析舱单抓取程序配置
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseRoleDisable(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("reload".equals(n.getName())) {
                    resultMap.put("roleDisable", Strings.nullToEmpty(n.getText()));
                }
            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseForwarderConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 解析告警忽略操作
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseIgnoreAlarm(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("healthUrl1".equals(n.getName())) {
                    resultMap.put("healthUrl1", Strings.nullToEmpty(n.getText()));
                } else if ("healthUrl2".equals(n.getName())) {
                    resultMap.put("healthUrl2", Strings.nullToEmpty(n.getText()));
                }
                if ("remark".equals(n.getName())) {
                    resultMap.put("remark", parseRemarkNode(n));
                }
            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseForwarderConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 解析舱单抓取程序配置
     *
     * @param node
     * @return
     */
    private Map<String, Object> parseForwarderConfig(SuperNode node) {
        try {
            Map<String, Object> resultMap = Maps.newHashMap();
            node.getNodeList().forEach(n -> {
                if ("healthUrl1".equals(n.getName())) {
                    resultMap.put("healthUrl1", Strings.nullToEmpty(n.getText()));
                } else if ("healthUrl2".equals(n.getName())) {
                    resultMap.put("healthUrl2", Strings.nullToEmpty(n.getText()));
                }
                if ("remark".equals(n.getName())) {
                    resultMap.put("remark", parseRemarkNode(n));
                }
            });
            return resultMap;
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "parseForwarderConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 解析msgAlarm节点
     *
     * @param node
     * @return
     */
    private MsgAlarmConfig parseMsgAlarmNode(Node node) {
        MsgAlarmConfig msgAlarmConfig = new MsgAlarmConfig();
        // 拆解name
        if (node.getAttributes().containsKey("name")) {
            msgAlarmConfig.setName(Strings.nullToEmpty(node.getAttributes().get("name")));
        }

        //拆解startTime
        if (node.getAttributes().containsKey("startTime")) {
            msgAlarmConfig.setStartTime(Strings.nullToEmpty(node.getAttributes().get("startTime")));
        }

        //拆解endTime
        if (node.getAttributes().containsKey("endTime")) {
            msgAlarmConfig.setEndTime(Strings.nullToEmpty(node.getAttributes().get("endTime")));
        }

        //拆解timeout
        if (node.getAttributes().containsKey("timeout")) {
            msgAlarmConfig.setTimeout(Strings.nullToEmpty(node.getAttributes().get("timeout")));
        }

        return msgAlarmConfig;
    }

    /**
     * 解析UDP节点
     *
     * @param node
     * @return
     */
    private UDPConfig parseUDPNode(Node node) {
        UDPConfig udpConfig = new UDPConfig();
        node.getSubNodeList().forEach(s -> {
            if ("host".equals(s.getName())) {
                udpConfig.setHost(Strings.nullToEmpty(s.getText()));
            }
            if ("port".equals(s.getName())) {
                udpConfig.setPort(Strings.nullToEmpty(s.getText()));
            }
            if ("timeout".equals(s.getName())) {
                udpConfig.setTimeout(Strings.nullToEmpty(s.getText()));
            }
        });
        return udpConfig;
    }


    /**
     * 解析NTP节点
     *
     * @param node
     * @return
     */
    private Map<String, String> parseNTPNode(Node node) {
        Map<String, String> map = Maps.newHashMap();
        node.getSubNodeList().forEach(s -> {
            if ("alarmTime".equals(s.getName())) {
                map.put("alarmTime", Strings.nullToEmpty(s.getText()));
            }
        });
        return map;
    }

    /**
     * 解析remark节点
     *
     * @param node
     * @return
     */
    private Map<String, String> parseRemarkNode(Node node) {
        Map<String, String> map = Maps.newHashMap();
        node.getSubNodeList().forEach(s -> {
            if ("personnel".equals(s.getName())) {
                map.put("personnel", Strings.nullToEmpty(s.getText()));
            }
            if ("emergencyplans".equals(s.getName())) {
                map.put("emergencyplans", Strings.nullToEmpty(s.getText()));
            }
        });

        return map;
    }


    /**
     * 保存bgs配置
     *
     * @param map
     * @throws Exception
     */
    public void saveBgsConfig(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 重新赋值配置信息
                bgsConfigMap = map;
                save();
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveBgsConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 保存database配置
     *
     * @param map
     * @throws Exception
     */
    public void saveDatabaseConfig(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 重新赋值配置信息
                databaseConfigMap = map;
                // 保存文件
                save();
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveDatabaseConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 保存mq配置
     *
     * @param map
     * @throws Exception
     */
    public void saveMQConfig(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 重新赋值配置信息
                mqConfigMap = map;
                // 保存文件
                save();
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveMQConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 保存appUpload配置
     *
     * @param map
     * @throws Exception
     */
    public void saveAppUploadConfig(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 清除原配置信息
                appUploadConfigMap.clear();

                if (map.containsKey("udp") && map.get("udp") != null) {
                    UDPConfig udp = JSON.parseObject(JSON.toJSONString(map.get("udp")), UDPConfig.class);
                    appUploadConfigMap.put("udp", udp);
                }

                if (map.containsKey("msgSplit") && map.get("msgSplit") != null) {
                    Map<String, String> m = JSON.parseObject(JSON.toJSONString(map.get("msgSplit")), Map.class);
                    Map<String, String> msgSplitMap = Maps.newHashMap();
                    if (m.containsKey("failureAlarm") && m.get("failureAlarm") != null) {
                        msgSplitMap.put("failureAlarm", m.get("failureAlarm"));
                    }
                    appUploadConfigMap.put("msgSplit", msgSplitMap);
                }

                if (map.containsKey("ntp") && map.get("ntp") != null) {
                    Map<String, String> m = JSON.parseObject(JSON.toJSONString(map.get("ntp")), Map.class);
                    Map<String, String> ntpMap = Maps.newHashMap();
                    if (m.containsKey("alarmTime") && m.get("alarmTime") != null) {
                        ntpMap.put("alarmTime", m.get("alarmTime"));
                    }
                    appUploadConfigMap.put("ntp", ntpMap);
                }
                if (map.containsKey("remark") && map.get("remark") != null) {
                    appUploadConfigMap.put("remark", map.get("remark"));
                }
                // 保存文件
                save();
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveAppUploadConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 保存airInfo配置
     *
     * @param map
     * @throws Exception
     */
    public void saveAirInfoConfig(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 重新赋值配置信息
                airInfoConfigMap = map;
                if (map.containsKey("msgAlarm") && map.get("msgAlarm") != null) {
                    List<MsgAlarmConfig> msgAlarmList = JSON.parseArray(JSON.toJSONString(map.get("msgAlarm")), MsgAlarmConfig.class);
                    airInfoConfigMap.put("msgAlarm", msgAlarmList);
                }
                // 保存文件
                save();
            }

        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveAirInfoConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 保存msgUpCenter配置
     *
     * @param map
     * @throws Exception
     */
    public void saveMsgUpCenterConfig(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 清除原配置信息
                msgUpCenterConfigMap.clear();

                if (map.containsKey("udp") && map.get("udp") != null) {
                    UDPConfig udp = JSON.parseObject(JSON.toJSONString(map.get("udp")), UDPConfig.class);
                    msgUpCenterConfigMap.put("udp", udp);
                }

                if (map.containsKey("ntp") && map.get("ntp") != null) {
                    Map<String, String> m = JSON.parseObject(JSON.toJSONString(map.get("ntp")), Map.class);
                    Map<String, String> ntpMap = Maps.newHashMap();
                    if (m.containsKey("alarmTime") && m.get("alarmTime") != null) {
                        ntpMap.put("alarmTime", m.get("alarmTime"));
                    }
                    msgUpCenterConfigMap.put("ntp", ntpMap);
                }

                if (map.containsKey("lineChart") && map.get("lineChart") != null) {
                    Map<String, String> m = JSON.parseObject(JSON.toJSONString(map.get("lineChart")), Map.class);
                    Map<String, String> lineChartMap = Maps.newHashMap();
                    if (m.containsKey("timespan") && m.get("timespan") != null) {
                        lineChartMap.put("timespan", m.get("timespan"));
                    }
                    if (m.containsKey("points") && m.get("points") != null) {
                        lineChartMap.put("points", m.get("points"));
                    }
                    msgUpCenterConfigMap.put("lineChart", lineChartMap);
                }
                if (map.containsKey("remark") && map.get("remark") != null) {
                    msgUpCenterConfigMap.put("remark", map.get("remark"));
                }

                // 保存文件
                save();
            }

        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveMsgUpCenterConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 保存website配置
     *
     * @param map
     * @throws Exception
     */
    public void saveWebsiteConfig(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 重新赋值配置信息
                websiteConfigMap = map;
                // 保存文件
                save();
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveWebsiteConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 保存舱单抓取程序配置
     *
     * @param map
     */
    public void saveForwarderConfig(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 重新赋值配置信息
                forwarderConfigMap = map;
                // 保存文件
                save();
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveForwarderConfig() error", ex);
            throw ex;
        }
    }

    /**
     * 保存忽略告警配置
     *
     * @param map
     */
    public void saveIgnoreAlarm(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 重新赋值配置信息
                ignoreAlarmMap = map;
                alarmIgnoreSet = getIgnoreAlarmSet();
                // 保存文件
                save();
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveIgnoreAlarm() error", ex);
            throw ex;
        }
    }

    /**
     * 保存重启权限
     *
     * @param map
     */
    public void saveRoleDisable(Map<String, Object> map) throws Exception {
        try {
            if (map != null && map.size() > 0) {
                // 重新赋值配置信息
                roleDisableMap = map;
                // 保存文件
                save();
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "saveRoleDisable() error", ex);
            throw ex;
        }
    }


    /**
     * 保存配置，生成xml文件
     */
    private void save() throws Exception {
        try {
            String strPath = FileUtil.getPath(CONFIG_FILE_NAME);
            if (!Strings.isNullOrEmpty(strPath)) {
                ADCCXML adccxml = buildXml();
                adccxml.createXMLFile(strPath, XMLPattern.PRETTY);
                Log.info(SystemConfigFactory.class, CONFIG_FILE_NAME + " save success.");
            } else {
                Log.error(SystemConfigFactory.class, "configuration file path not exist");
            }
        } catch (Exception ex) {
            Log.error(SystemConfigFactory.class, "save() error", ex);
            throw ex;
        }
    }


    /**
     * 创建XML
     *
     * @return
     * @throws Exception
     */
    private ADCCXML buildXml() {
        ADCCXML adccxml = ADCCXMLFactory.getInstance().createADCCXML();
        adccxml.getRoot().put("version", "1.0");
        adccxml.getRoot().put("type", "systemConfig");

        // bgs
        SuperNode bgsNode = new SuperNode("bgs");
        if (bgsConfigMap.containsKey("healthCheck")) {
            Node healthCheckNode = new Node("healthCheck");
            healthCheckNode.setText(Strings.nullToEmpty((String) bgsConfigMap.get("healthCheck")));
            bgsNode.getNodeList().add(healthCheckNode);
        }
        if (bgsConfigMap.containsKey("remark")) {
            bgsNode.getNodeList().add(saveremark(bgsConfigMap));
        }


        // database
        SuperNode databaseNode = new SuperNode("database");
        if (databaseConfigMap.containsKey("warn")) {
            Node warnNode = new Node("warn");
            warnNode.setText(Strings.nullToEmpty((String) databaseConfigMap.get("warn")));
            databaseNode.getNodeList().add(warnNode);
        }
        if (databaseConfigMap.containsKey("error")) {
            Node errorNode = new Node("error");
            errorNode.setText(Strings.nullToEmpty((String) databaseConfigMap.get("error")));
            databaseNode.getNodeList().add(errorNode);
        }
        if (databaseConfigMap.containsKey("diskUsage")) {
            Node diskUsageNode = new Node("diskUsage");
            diskUsageNode.setText(Strings.nullToEmpty((String) databaseConfigMap.get("diskUsage")));
            databaseNode.getNodeList().add(diskUsageNode);
        }
        if (databaseConfigMap.containsKey("tablespaceUsage")) {
            Node tablespaceUsageNode = new Node("tablespaceUsage");
            tablespaceUsageNode.setText(Strings.nullToEmpty((String) databaseConfigMap.get("tablespaceUsage")));
            databaseNode.getNodeList().add(tablespaceUsageNode);
        }
        if (databaseConfigMap.containsKey("remark")) {
            databaseNode.getNodeList().add(saveremark(databaseConfigMap));
        }


        // mq
        SuperNode mqNode = new SuperNode("mq");
        if (mqConfigMap.containsKey("url")) {
            Node urlNode = new Node("url");
            urlNode.setText(Strings.nullToEmpty((String) mqConfigMap.get("url")));
            mqNode.getNodeList().add(urlNode);
        }
        if (mqConfigMap.containsKey("uplinkTopic")) {
            Node uplinkTopicNode = new Node("uplinkTopic");
            uplinkTopicNode.setText(Strings.nullToEmpty((String) mqConfigMap.get("uplinkTopic")));
            mqNode.getNodeList().add(uplinkTopicNode);
        }
        if (mqConfigMap.containsKey("downlinkTopic")) {
            Node downlinkTopicNode = new Node("downlinkTopic");
            downlinkTopicNode.setText(Strings.nullToEmpty((String) mqConfigMap.get("downlinkTopic")));
            mqNode.getNodeList().add(downlinkTopicNode);
        }
        if (mqConfigMap.containsKey("remark")) {
            mqNode.getNodeList().add(saveremark(mqConfigMap));
        }


        // appupload
        SuperNode appUploadNode = new SuperNode("appupload");
        if (appUploadConfigMap.containsKey("udp")) {
            Node udpNode = new Node("udp");
            UDPConfig udpConfig = (UDPConfig) appUploadConfigMap.get("udp");
            udpNode.addSubNode("host", Strings.nullToEmpty(udpConfig.getHost()));
            udpNode.addSubNode("port", Strings.nullToEmpty(udpConfig.getPort()));
            udpNode.addSubNode("timeout", Strings.nullToEmpty(udpConfig.getTimeout()));
            appUploadNode.getNodeList().add(udpNode);
        }
        if (appUploadConfigMap.containsKey("msgSplit")) {
            Node msgSplitNode = new Node("msgSplit");
            Map<String, String> map = (Map<String, String>) appUploadConfigMap.get("msgSplit");
            if (map.containsKey("failureAlarm")) {
                msgSplitNode.addSubNode("failureAlarm", Strings.nullToEmpty(map.get("failureAlarm")));
            }
            appUploadNode.getNodeList().add(msgSplitNode);
        }
        if (appUploadConfigMap.containsKey("ntp")) {
            Node ntpNode = new Node("ntp");
            Map<String, String> map = (Map<String, String>) appUploadConfigMap.get("ntp");
            if (map.containsKey("alarmTime")) {
                ntpNode.addSubNode("alarmTime", Strings.nullToEmpty(map.get("alarmTime")));
            }
            appUploadNode.getNodeList().add(ntpNode);
        }
        if (appUploadConfigMap.containsKey("remark")) {
            appUploadNode.getNodeList().add(saveremark(appUploadConfigMap));
        }


        // airInfo
        SuperNode airInfoNode = new SuperNode("airInfo");
        if (airInfoConfigMap.containsKey("url")) {
            Node urlNode = new Node("url");
            urlNode.setText(Strings.nullToEmpty((String) airInfoConfigMap.get("url")));
            airInfoNode.getNodeList().add(urlNode);
        }
        if (airInfoConfigMap.containsKey("topic")) {
            Node topicNode = new Node("topic");
            topicNode.setText(Strings.nullToEmpty((String) airInfoConfigMap.get("topic")));
            airInfoNode.getNodeList().add(topicNode);
        }
        if (airInfoConfigMap.containsKey("msgAlarm")) {
            Node msgAlarmNode = new Node("msgAlarm");
            List<MsgAlarmConfig> list = (List<MsgAlarmConfig>) airInfoConfigMap.get("msgAlarm");
            list.forEach(a -> {
                Node node = new Node();
                node.getAttributes().put("name", Strings.nullToEmpty(a.getName()));
                node.getAttributes().put("startTime", Strings.nullToEmpty(a.getStartTime()));
                node.getAttributes().put("endTime", Strings.nullToEmpty(a.getEndTime()));
                node.getAttributes().put("timeout", Strings.nullToEmpty(a.getTimeout()));
                msgAlarmNode.getSubNodeList().add(node);
            });
            airInfoNode.getNodeList().add(msgAlarmNode);
        }
        if (airInfoConfigMap.containsKey("remark")) {
            airInfoNode.getNodeList().add(saveremark(airInfoConfigMap));
        }

        // msgUpCenter
        SuperNode msgUpCenterNode = new SuperNode("msgupcenter");
        if (msgUpCenterConfigMap.containsKey("udp")) {
            Node udpNode = new Node("udp");
            UDPConfig udpConfig = (UDPConfig) msgUpCenterConfigMap.get("udp");
            udpNode.addSubNode("host", Strings.nullToEmpty(udpConfig.getHost()));
            udpNode.addSubNode("port", Strings.nullToEmpty(udpConfig.getPort()));
            udpNode.addSubNode("timeout", Strings.nullToEmpty(udpConfig.getTimeout()));
            msgUpCenterNode.getNodeList().add(udpNode);
        }
        if (msgUpCenterConfigMap.containsKey("ntp")) {
            Node ntpNode = new Node("ntp");
            Map<String, String> map = (Map<String, String>) msgUpCenterConfigMap.get("ntp");
            if (map.containsKey("alarmTime")) {
                ntpNode.addSubNode("alarmTime", Strings.nullToEmpty(map.get("alarmTime")));
            }
            msgUpCenterNode.getNodeList().add(ntpNode);
        }
        if (msgUpCenterConfigMap.containsKey("lineChart")) {
            Node lineChartNode = new Node("lineChart");
            Map<String, String> map = (Map<String, String>) msgUpCenterConfigMap.get("lineChart");
            if (map.containsKey("timespan")) {
                lineChartNode.addSubNode("timespan", Strings.nullToEmpty(map.get("timespan")));
            }
            if (map.containsKey("points")) {
                lineChartNode.addSubNode("points", Strings.nullToEmpty(map.get("points")));
            }
            msgUpCenterNode.getNodeList().add(lineChartNode);
        }
        if (msgUpCenterConfigMap.containsKey("remark")) {
            msgUpCenterNode.getNodeList().add(saveremark(msgUpCenterConfigMap));
        }

        // website
        SuperNode websiteNode = new SuperNode("website");
        if (websiteConfigMap.containsKey("url1")) {
            Node urlNode1 = new Node("url1");
            urlNode1.setText(Strings.nullToEmpty((String) websiteConfigMap.get("url1")));
            websiteNode.getNodeList().add(urlNode1);
        }

        if (websiteConfigMap.containsKey("url2")) {
            Node urlNode2 = new Node("url2");
            urlNode2.setText(Strings.nullToEmpty((String) websiteConfigMap.get("url2")));
            websiteNode.getNodeList().add(urlNode2);
        }
        if (websiteConfigMap.containsKey("remark")) {
            websiteNode.getNodeList().add(saveremark(websiteConfigMap));
        }

        // 舱单转发程序
        SuperNode forwarderNode = new SuperNode("forwarder");
        if (forwarderConfigMap.containsKey("healthUrl1")) {
            Node urlNode = new Node("healthUrl1");
            urlNode.setText(Strings.nullToEmpty((String) forwarderConfigMap.get("healthUrl1")));
            forwarderNode.getNodeList().add(urlNode);
        }
        if (forwarderConfigMap.containsKey("healthUrl2")) {
            Node urlNode = new Node("healthUrl2");
            urlNode.setText(Strings.nullToEmpty((String) forwarderConfigMap.get("healthUrl2")));
            forwarderNode.getNodeList().add(urlNode);
        }
        if (forwarderConfigMap.containsKey("remark")) {
            forwarderNode.getNodeList().add(saveremark(forwarderConfigMap));
        }

        //忽略告警配置项
        SuperNode alarm = new SuperNode("alarm");
        if (ignoreAlarmMap.containsKey("ignore") && ((ArrayList) ignoreAlarmMap.get("ignore")).size() > 0) {
            ArrayList<Node> nodes = new ArrayList<>();
            Node ignore = new Node("ignoreItem");
            ArrayList<Map> target = (ArrayList<Map>) ignoreAlarmMap.get("ignore");
            ArrayList<IgnoreAlarmVO> ignoreAlarmVOS = parseMapToIgnoreList(target);
            for (IgnoreAlarmVO ignoreAlarmVO : ignoreAlarmVOS) {
                Node node = new Node();
                HashMap<String, String> attribute = new HashMap<>();
                attribute.put("id", ignoreAlarmVO.getId());
                attribute.put("key", ignoreAlarmVO.getKey());
                node.setAttributes(attribute);
                node.setText(ignoreAlarmVO.getValue());
                nodes.add(node);
            }
            ignore.setSubNodeList(nodes);
            alarm.getNodeList().add(ignore);
        } else {
            Node ignore = new Node("ignoreItem");
            alarm.getNodeList().add(ignore);
        }

        if (ignoreAlarmMap.containsKey("alarm") && ((ArrayList) ignoreAlarmMap.get("alarm")).size() > 0) {
            ArrayList<Node> nodes = new ArrayList<>();
            Node alarmItem = new Node("alarmItem");
            ArrayList<Map> target = (ArrayList<Map>) ignoreAlarmMap.get("alarm");
            ArrayList<IgnoreAlarmVO> ignoreAlarmVOS = parseMapToIgnoreList(target);
            for (IgnoreAlarmVO ignoreAlarmVO : ignoreAlarmVOS) {
                Node node = new Node();
                HashMap<String, String> attribute = new HashMap<>();
                attribute.put("id", ignoreAlarmVO.getId());
                attribute.put("key", ignoreAlarmVO.getKey());
                node.setAttributes(attribute);
                node.setText(ignoreAlarmVO.getValue());
                nodes.add(node);
            }
            alarmItem.setSubNodeList(nodes);
            alarm.getNodeList().add(alarmItem);
        } else {
            Node alarmItem = new Node("alarmItem");
            alarm.getNodeList().add(alarmItem);
        }

        //禁止非admin用户重启
        SuperNode roleDisable = new SuperNode("permissions");
        if (roleDisableMap.containsKey("roleDisable")) {
            Node reload = new Node("reload");
            reload.setText((String) roleDisableMap.get("roleDisable"));
            roleDisable.getNodeList().add(reload);
        }
        adccxml.addSuperNode(bgsNode);
        adccxml.addSuperNode(databaseNode);
        adccxml.addSuperNode(mqNode);
        adccxml.addSuperNode(appUploadNode);
        adccxml.addSuperNode(airInfoNode);
        adccxml.addSuperNode(msgUpCenterNode);
        adccxml.addSuperNode(websiteNode);
        adccxml.addSuperNode(forwarderNode);
        adccxml.addSuperNode(alarm);
        adccxml.addSuperNode(roleDisable);
        return adccxml;
    }

    /**
     * 生成remark标签，xml
     *
     * @return
     */
    private Node saveremark(Map<String, Object> mapSource) {
        Node lineChartNode = new Node("remark");
        Map<String, String> map = (Map<String, String>) mapSource.get("remark");
        if (map.containsKey("personnel")) {
            lineChartNode.addSubNode("personnel", Strings.nullToEmpty(map.get("personnel")));
        }
        if (map.containsKey("emergencyplans")) {
            lineChartNode.addSubNode("emergencyplans", Strings.nullToEmpty(map.get("emergencyplans")));
        }
        return lineChartNode;
    }

    /**
     * 读取告警忽略项配置
     *
     * @return
     * @throws ParserConfigurationException
     * @throws IOException
     * @throws SAXException
     */
    public static HashMap<String, Object> parseALarmIgnore() throws ParserConfigurationException, IOException, SAXException {
        File file = FileUtil.readFile(CONFIG_FILE_NAME);
        FileInputStream fileInputStream = new FileInputStream(file);
        try {
            HashMap<String, Object> result = new HashMap<>();
            List<Map> alarmVOS = new ArrayList<>();
            List<Map> ignoreVOS = new ArrayList<>();

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(fileInputStream);
            Element root = doc.getDocumentElement();
            NodeList nodes = root.getElementsByTagName("alarmItem");
            Element element = (Element) nodes.item(0);
            NodeList childNodes = element.getElementsByTagName("node");

            for (int i = 0; i < childNodes.getLength(); i++) {
                Element elementchildNodes = (Element) childNodes.item(i);
                Map<String, String> ignoreAlarmVO = new HashMap<>();
                ignoreAlarmVO.put("id", elementchildNodes.getAttribute("id"));
                ignoreAlarmVO.put("key", elementchildNodes.getAttribute("key"));
                ignoreAlarmVO.put("value", elementchildNodes.getTextContent());
                alarmVOS.add(ignoreAlarmVO);
            }
            result.put("alarm", alarmVOS);

            NodeList ignoreItem = root.getElementsByTagName("ignoreItem");
            Element elementIgnoreItem = (Element) ignoreItem.item(0);
            NodeList childNodesIgnoreItem = elementIgnoreItem.getElementsByTagName("node");

            for (int i = 0; i < childNodesIgnoreItem.getLength(); i++) {
                Element elementchildNodes = (Element) childNodesIgnoreItem.item(i);
                Map<String, String> ignoreAlarmVO = new HashMap<>();
                ignoreAlarmVO.put("id", elementchildNodes.getAttribute("id"));
                ignoreAlarmVO.put("key", elementchildNodes.getAttribute("key"));
                ignoreAlarmVO.put("value", elementchildNodes.getTextContent());
                ignoreVOS.add(ignoreAlarmVO);
            }
            result.put("ignore", ignoreVOS);
            return result;
        } finally {
            fileInputStream.close();
        }
    }

    /**
     * map转成对象结合
     *
     * @param
     * @return
     */
    public ArrayList<IgnoreAlarmVO> parseMapToIgnoreList(List<Map> source) {
        ArrayList<IgnoreAlarmVO> result = new ArrayList<>();
        if (source != null && source.size() > 0) {
            for (Map map : source) {
                IgnoreAlarmVO ignoreAlarmVO = new IgnoreAlarmVO();
                ignoreAlarmVO.setId((String) map.get("id"));
                ignoreAlarmVO.setKey((String) map.get("key"));
                ignoreAlarmVO.setValue((String) map.get("value"));
                result.add(ignoreAlarmVO);
            }
        }
        return result;
    }

    public Set<String> getIgnoreAlarmSet() {
        Set<String> alarmIgnoreAlarm = new HashSet<>();
        List<Map> ignoreVOS = (List<Map>) ignoreAlarmMap.get("ignore");
        if (ignoreVOS != null && ignoreVOS.size() > 0) {
            for (Map ignoreVO : ignoreVOS) {
                alarmIgnoreAlarm.add(ignoreVO.get("id").toString());
            }
        }
        return alarmIgnoreAlarm;
    }
}
